<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>asyncio performance &#8212; Asyncio Documentation 0.0 documentation</title>
    
    <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="https://media.readthedocs.org/css/badge_only.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    './',
        VERSION:     '0.0',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true,
        SOURCELINK_SUFFIX: '.txt'
      };
    </script>
    <script type="text/javascript" src="https://media.readthedocs.org/javascript/jquery/jquery-2.0.3.min.js"></script>
    <script type="text/javascript" src="https://media.readthedocs.org/javascript/jquery/jquery-migrate-1.2.1.min.js"></script>
    <script type="text/javascript" src="https://media.readthedocs.org/javascript/underscore.js"></script>
    <script type="text/javascript" src="https://media.readthedocs.org/javascript/doctools.js"></script>
    <script type="text/javascript" src="https://media.readthedocs.org/javascript/readthedocs-doc-embed.js"></script>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Learn asyncio if you come from Twisted" href="twisted.html" />
    <link rel="prev" title="HTTP client example" href="http_client.html" />
   
  <link rel="stylesheet" href="_static/custom.css" type="text/css" />
  
  
  <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />

  
<!-- RTD Extra Head -->

<!-- 
Always link to the latest version, as canonical.
http://docs.readthedocs.org/en/latest/canonical.html
-->
<link rel="canonical" href="http://asyncio.readthedocs.io/en/latest/performance.html" />

<link rel="stylesheet" href="https://media.readthedocs.org/css/readthedocs-doc-embed.css" type="text/css" />

<script type="text/javascript" src="_static/readthedocs-data.js"></script>

<!-- Add page-specific data, which must exist in the page js, not global -->
<script type="text/javascript">
READTHEDOCS_DATA['page'] = 'performance' 		
READTHEDOCS_DATA['source_suffix'] = '.rst'
</script>

<script type="text/javascript" src="_static/readthedocs-dynamic-include.js"></script>

<!-- end RTD <extrahead> --></head>
  <body role="document">
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="asyncio-performance">
<h1>asyncio performance<a class="headerlink" href="#asyncio-performance" title="Permalink to this headline">¶</a></h1>
<p>Random notes about tuning asyncio for performance. Performance means two
different terms which might be incompatible:</p>
<ul class="simple">
<li>Number of concurrent requests per second</li>
<li>Request latency in seconds: min/average/max time to complete a request</li>
</ul>
<div class="section" id="architecture-worker-processes">
<h2>Architecture: Worker processes<a class="headerlink" href="#architecture-worker-processes" title="Permalink to this headline">¶</a></h2>
<p>Because of its GIL, CPython is basically only able to use 1 CPU. To increase
the number of concurrent requests, one solution is to spawn multiple worker
processes. See for example:</p>
<ul class="simple">
<li><a class="reference external" href="http://docs.gunicorn.org/en/stable/design.html">Gunicorn</a></li>
<li><a class="reference external" href="http://pythonhosted.org/api_hour/">API-Hour</a></li>
</ul>
</div>
<div class="section" id="stream-limits">
<h2>Stream limits<a class="headerlink" href="#stream-limits" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://docs.python.org/dev/library/asyncio-stream.html#streamreader">limit parameter of StreamReader/open_connection()</a></li>
<li><a class="reference external" href="https://docs.python.org/dev/library/asyncio-protocol.html#asyncio.WriteTransport.set_write_buffer_limits">set_write_buffer_limits() low/high water mark on writing for transports</a></li>
</ul>
<p>aiohttp uses <code class="docutils literal"><span class="pre">set_writer_buffer_limits(0)</span></code> for backpressure support and
implemented their own buffering, see:</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/aio-libs/aiohttp/pull/1478/files">aio-libs/aiohttp#1369</a></li>
<li><a class="reference external" href="https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/">Some thoughts on asynchronous API design in a post-async/await world</a>
(November, 2016) by Nathaniel J. Smith</li>
</ul>
</div>
<div class="section" id="tcp-nodelay">
<h2>TCP_NODELAY<a class="headerlink" href="#tcp-nodelay" title="Permalink to this headline">¶</a></h2>
<p>Since Python 3.6, asyncio now sets the <code class="docutils literal"><span class="pre">TCP_NODELAY</span></code> option on newly created
sockets: disable the Nagle algorithm for send coalescing. Disable segment
buffering so data can be sent out to peer as quickly as possible, so this is
typically used to improve network utilisation.</p>
<p>See <a class="reference external" href="https://en.wikipedia.org/wiki/Nagle%27s_algorithm">Nagle&#8217;s algorithm</a>.</p>
</div>
<div class="section" id="tcp-quickack">
<h2>TCP_QUICKACK<a class="headerlink" href="#tcp-quickack" title="Permalink to this headline">¶</a></h2>
<p>(This option is not used by asyncio by default.)</p>
<p>The <code class="docutils literal"><span class="pre">TCP_QUICKACK</span></code> option can be used to send out acknowledgements as early
as possible than delayed under some protocol level exchanging, and it&#8217;s not
stable/permanent, subsequent TCP transactions (which may happen under the hood)
can disregard this option depending on actual protocol level processing or any
actual disagreements between user setting and stack behaviour.</p>
</div>
<div class="section" id="tune-the-linux-kernel">
<h2>Tune the Linux kernel<a class="headerlink" href="#tune-the-linux-kernel" title="Permalink to this headline">¶</a></h2>
<p>Linux TCP sysctls:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">/proc/sys/net/ipv4/tcp_mem</span></code></li>
<li><code class="docutils literal"><span class="pre">/proc/sys/net/core/rmem_default</span></code> and <code class="docutils literal"><span class="pre">/proc/sys/net/core/rmem_max</span></code>:
The default and maximum amount for the receive socket memory</li>
<li><code class="docutils literal"><span class="pre">/proc/sys/net/core/wmem_default</span></code> and <code class="docutils literal"><span class="pre">/proc/sys/net/core/wmem_max</span></code>:
The default and maximum amount for the send socket memory</li>
<li><code class="docutils literal"><span class="pre">/proc/sys/net/core/optmem_max</span></code>: The maximum amount of option memory
buffers</li>
<li><code class="docutils literal"><span class="pre">net.ipv4.tcp_no_metrics_save</span></code></li>
<li><code class="docutils literal"><span class="pre">net.core.netdev_max_backlog</span></code>: Set maximum number of packets, queued on the
INPUT side, when the interface receives packets faster than kernel can
process them.</li>
</ul>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Asyncio Documentation</a></h1>






<p>
<iframe src="https://ghbtns.com/github-btn.html?user=asyncio-doc&repo=asyncio-doc&type=star&count=true&size=large&v=2"
  allowtransparency="true" frameborder="0" scrolling="0" width="200px" height="35px"></iframe>
</p>





<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="why_asyncio.html">Why use asyncio?</a></li>
<li class="toctree-l1"><a class="reference internal" href="getting_started.html">Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="hello_world.html">Hello World</a></li>
<li class="toctree-l1"><a class="reference internal" href="hello_clock.html">Hello Clock</a></li>
<li class="toctree-l1"><a class="reference internal" href="http_client.html">HTTP client example</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">asyncio performance</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#architecture-worker-processes">Architecture: Worker processes</a></li>
<li class="toctree-l2"><a class="reference internal" href="#stream-limits">Stream limits</a></li>
<li class="toctree-l2"><a class="reference internal" href="#tcp-nodelay">TCP_NODELAY</a></li>
<li class="toctree-l2"><a class="reference internal" href="#tcp-quickack">TCP_QUICKACK</a></li>
<li class="toctree-l2"><a class="reference internal" href="#tune-the-linux-kernel">Tune the Linux kernel</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="twisted.html">Learn asyncio if you come from Twisted</a></li>
<li class="toctree-l1"><a class="reference internal" href="getting_help.html">Getting Help</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="tcp_echo.html">TCP echo client and server</a></li>
<li class="toctree-l1"><a class="reference internal" href="threads.html">Threads</a></li>
<li class="toctree-l1"><a class="reference internal" href="subprocess.html">Subprocess</a></li>
<li class="toctree-l1"><a class="reference internal" href="producer_consumer.html">Producer/consumer</a></li>
<li class="toctree-l1"><a class="reference internal" href="debug_mode.html">Asyncio Debug Mode</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="webscraper.html">Web Scraping</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="glossary.html">Glossary</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="README.html">Asyncio documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#notes-to-writers">Notes to writers</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#ideas">Ideas</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#how-to-install-sphinx">How to install Sphinx</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#how-to-build-the-documentation">How to build the documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#see-also">See also</a></li>
</ul>

<div class="relations">
<h3>Related Topics</h3>
<ul>
  <li><a href="index.html">Documentation overview</a><ul>
      <li>Previous: <a href="http_client.html" title="previous chapter">HTTP client example</a></li>
      <li>Next: <a href="twisted.html" title="next chapter">Learn asyncio if you come from Twisted</a></li>
  </ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <div><input type="text" name="q" /></div>
      <div><input type="submit" value="Go" /></div>
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">asyncio performance</a><ul>
<li><a class="reference internal" href="#architecture-worker-processes">Architecture: Worker processes</a></li>
<li><a class="reference internal" href="#stream-limits">Stream limits</a></li>
<li><a class="reference internal" href="#tcp-nodelay">TCP_NODELAY</a></li>
<li><a class="reference internal" href="#tcp-quickack">TCP_QUICKACK</a></li>
<li><a class="reference internal" href="#tune-the-linux-kernel">Tune the Linux kernel</a></li>
</ul>
</li>
</ul>

  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/performance.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="footer">
      &copy;2016, Victor Stinner.
      
      |
      Powered by <a href="http://sphinx-doc.org/">Sphinx 1.5.3</a>
      &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.10</a>
      
      |
      <a href="_sources/performance.rst.txt"
          rel="nofollow">Page source</a>
    </div>

    
    <a href="https://github.com/asyncio-doc/asyncio-doc" class="github">
        <img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"  class="github"/>
    </a>
    

    
  </body>
</html>